/**************************************************************************//**
 * @item     CosyOS-III 例程（服务应用）
 * @file     event_ressus.c
 * @brief    事件同步_恢复挂起
 * @details  通过{恢复任务->挂起自身}，实现中断对任务的事件同步。
 * @note     事件处理线程（task_1）中，无法实现超时处理机制。
 * @author   迟凯峰
 * @version  V1.0.0
 * @date     2025.10.21
 ******************************************************************************/

/*-----------------------------------------------*
 | 服务              | 描述                      |
 |-------------------+---------------------------|
 | uSuspendTasking() | 任务中挂起自身            |
 |-------------------+---------------------------|
 | iResumeTask(task) | 中断中恢复任务 - FIFO服务 |
 |-------------------+---------------------------|
 | pResumeTask(task) | 中断中恢复任务 - FLAG服务 |
 *-----------------------------------------------*/

#if 1 /* 编译开关 */

#include "CosyOS.H"

bool resume_task_1 = false; // 恢复task_1标志位，用于FLAG服务

/**
 * \brief    task_1
 * \details  协作处理更为耗时的事务。
 */
uCreateTask(task_1, 1, 384, 0, 0)
{
    while(1){
        uSuspendTasking();
        /* 处理事件 开始 */
        
        /* 处理事件 结束 */
    }
}

/**
 * \brief    某中断
 * \details  先对事件做必要的紧急处理，再同步至task_1 做后续处理。
 */
void XXXx_IRQHandler(void) // interrupt XXXx_VECTOR
{
    /* 清中断标志位 开始 */
    
    /* 清中断标志位 结束 */
    /* 紧急处理事件 开始 */
    
    /* 紧急处理事件 结束 */
    /* 同步至task_1 开始 */// 可采用 FIFO服务 或 FLAG服务
    /* 采用 FIFO服务 */
    iResumeTask(task_1);   // 恢复task_1
    /* 采用 FLAG服务 */
////resume_task_1 = true;  // 先设置标志位
////iPendSV_Set();         // 再触发PendSV，而后在 pendsv_hook 中调用并执行服务
    /* 同步至task_1 结束 */
}

/**
 * \brief    挂起服务钩子
 * \details  当需要在中断中完成特定的服务功能时，可先设置一个标志位，再触发 PendSV；
             而后在 pendsv_hook 中查询该标志位，为真就清除标志位，而后调用相应服务。
 * \note     此处应调用前缀为“p”的中断挂起服务。
 */
void pendsv_hook(void) MCUCFG_OSIT_ATTRIBUTE
{
    if(resume_task_1){ // 查询标志位
        resume_task_1 = false; // 清除标志位
        pResumeTask(task_1);   // 恢复task_1
    }
}

/** 启动钩子 */
void start_hook(void)
{
    uStartTask_Ready(task_1); // 启动task_1，初始状态为就绪状态
}

#endif
